package study.itwill.team5.admin;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import study.itwill.common.DBHandler;
import study.itwill.common.Util;

/**
 * 관리자 계정 - 추가, 수정, 삭제, 조회, 리스트, 로그인, 로그아웃 기능을 가진 클래스
 */
public class Admin {
	
	// Logger 클래스의 인스턴스를 받아온다.
	static Logger logger = Logger.getLogger(Admin.class);
		
	private static final String TABLE = "admin";
	
	/**
	 * 관리자 계정추가
	 * @param	id : 관리자 아이디
	 * @param	pw : 관리자 비밀번호
	 * @param	level : 관리자 등급
	 * @param	comment : 아이디 사용용도에 대한 코멘트
	 * @return	int : 추가된 회원에 대한 일련번호를 리턴
	 */
	public int addAdmin(String admin_id, String admin_pw, int admin_level, String admin_comment) {
		//-----------------------------------------
		// 메서드 시작
		//-----------------------------------------
		logger.debug("=============== method start >> addAdmin");
		logger.debug("[PARAMS] admin_id=" + admin_id);
		logger.debug("[PARAMS] admin_pw=" + admin_pw);
		logger.debug("[PARAMS] admin_level=" + admin_level);
		logger.debug("[PARAMS] admin_comment=" + admin_comment);
		
		int seq = -1;
		
		// SQL 인젝션 방어
		admin_id = admin_id.replace("'", "\'");
		admin_pw = admin_pw.replace("'", "\'");
		admin_comment = admin_comment.replace("'", "\'");
		
		
		// 트랜젝션에 대한 판단이 잘 서지 않는다면, 무조건 하면 된다.
		DBHandler.beginTrans();
		
		// INSERT 처리를 위한 구현
		String sql = "INSERT INTO admin("
	            + "admin_id, admin_pw, admin_level, admin_comment, reg_date, edit_date"
	            + ") VALUES ('%s', '%s', %d, '%s', '%s', '%s');";
		
		boolean result = DBHandler.execSql(sql, admin_id, admin_pw,	admin_level, admin_comment, Util.getTime(), Util.getTime());
		
		//-----------------------------------------
		// 결과처리
		//-----------------------------------------
		if(result) {
			DBHandler.commit();
			seq = DBHandler.getMax(TABLE, "seq", null);
			logger.debug("처리결과 >> " + seq + "번 관리자 계정 등록 성공");
		} else {
			DBHandler.rollback();
			logger.error("처리결과 >> 관리자 계정 추가 실패");
		}
		
		logger.debug("=============== method end >> addAdmin");
		
		
		return seq;
	}
	
	/**
	 * 관리자 계정수정
	 * @param	seq : 관리자 일련번호
	 * @param	id : 관리자 아이디
	 * @param	pw : 관리자 비밀번호
	 * @param	level : 관리자 등급
	 * @param	comment : 아이디 사용용도에 대한 코멘트
	 * @return	boolean : 수정처리의 결과유무에 따라 리턴
	 */
	public boolean editAdmin(int seq, String admin_id, String admin_pw, int admin_level, String admin_comment) {
		logger.debug("=============== method start >> editAdmin");
		logger.debug("[PARAMS] seq=" + seq);
		logger.debug("[PARAMS] admin_id=" + admin_id);
		logger.debug("[PARAMS] admin_pw=" + admin_pw);
		logger.debug("[PARAMS] admin_level=" + admin_level);
		logger.debug("[PARAMS] admin_comment=" + admin_comment);
		
		// SQL 인젝션 방어
		admin_id = admin_id.replace("'", "\'");
		admin_pw = admin_pw.replace("'", "\'");
		admin_comment = admin_comment.replace("'", "\'");
		
		boolean result = false;
		
		DBHandler.beginTrans();
		
		String sql = "UPDATE admin "
				+ "SET admin_id = '%s', admin_pw = '%s', admin_level = %d, admin_comment = '%s', edit_date = '%s' "
				+ "WHERE seq = %d;";
		
		result = DBHandler.execSql(sql, admin_id, admin_pw, admin_level, admin_comment, Util.getTime(), seq);
		
		if(result) {
			DBHandler.commit();
			logger.debug("처리결과 >> " + seq + "번 관리자 계정 수정성공");
		} else {
			DBHandler.rollback();
			logger.error("처리결과 >> 데이터 수정 실패 ");
		}
		
		logger.debug("=============== method end >> editAdmin");
		
		return result;
	}
	
	/**
	 * 관리자 계정삭제
	 * @param	seq : 관리자 계정의 일련번호
	 * @return	boolean : 삭제처리의 결과유무에 따라 리턴
	 */
	public boolean deleteAdmin(int seq) {
		logger.debug("=============== method start >> deleteAdmin");
		logger.debug("[PARAMS] seq=" + seq);
		
		boolean result = false;
		
		DBHandler.beginTrans();
		
		String sql = "DELETE FROM admin WHERE seq = %d;";
		result = DBHandler.execSql(sql, seq);
		
		if(result) {
			DBHandler.commit();
			logger.debug("처리결과 >> " + seq + "번 어드민 계정 삭제 성공");
		} else {
			DBHandler.rollback();
			logger.error("처리결과 >> 데이터 삭제 실패 ");
		}
		
		logger.debug("=============== method end >> deleteAdmin");
		
		return result;
	}
	
	/**
	 * 관리자 계정조회
	 * @param	seq : 관리자 계정의 일련번호
	 * @return	AdminItem : 관리자한명 계정의 객체로 리턴
	 */
	public AdminItem viewAdmin(int seq) {
		logger.debug("=============== method start >> viewAdmin");
		logger.debug("[PARAMS] seq=" + seq);
		
		AdminItem item = null;
		
		// 데이터 조회
		String sql = "SELECT seq, admin_id, admin_pw, admin_level, admin_comment, reg_date, edit_date "
				+ "FROM admin "
				+ "WHERE seq = %d;";
		
		ResultSet rs = DBHandler.getResult(sql, seq);
		
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				rs.next();
				
				// 1) ResultSet의 모든 데이터를 변수로 추출
				int admin_seq = rs.getInt(1);
				String admin_id = rs.getString(2);
				String admin_pw = rs.getString(3);
				int admin_level = rs.getInt(4);
				String admin_comment = rs.getString(5);
				String reg_date = rs.getString(6);
				String edit_date = rs.getString(7);
				
				// 2) 추출된 값을 객체로 구성
				item = new AdminItem(admin_seq, admin_id, admin_pw, admin_level, admin_comment, reg_date, edit_date);
				
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 3) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
		
		if(item == null) {
			logger.error("데이터 조회 실패");
		} else {
			logger.debug("데이터 조회 성공");
			logger.debug(item.toString());
		}
				
		logger.debug("=============== method end >> viewAdmin");
		
		return item;
	}
	
	/**
	 * 관리자 계정 리스트조회
	 * @return	ArrayList<AdminItem> : 관리자들 계정의 객체배열로 리턴
	 */
	public ArrayList<AdminItem> listAdmin() {
		logger.debug("=============== method start >> listAdmin");
		
		ArrayList<AdminItem> list = null;
		
		// 데이터 조회
		String sql = "SELECT seq, admin_id, admin_pw, admin_level, admin_comment, reg_date, edit_date "
				+ "FROM admin;";
		
		ResultSet rs = DBHandler.getResult(sql);
		
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				list = new ArrayList<AdminItem>();
				
				while(rs.next()) {
					
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int admin_seq = rs.getInt(1);
					String admin_id = rs.getString(2);
					String admin_pw = rs.getString(3);
					int admin_level = rs.getInt(4);
					String admin_comment = rs.getString(5);
					String reg_date = rs.getString(6);
					String edit_date = rs.getString(7);
					
					// 2) 추출된 값을 객체로 구성
					AdminItem item = new AdminItem(admin_seq, admin_id, admin_pw, admin_level, admin_comment, reg_date, edit_date);
					
					// 3) ArrayList에 추가
					list.add(item);
				}
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
		
		if(list == null) {
			logger.error("데이터 조회 실패");
		} else {
			logger.debug("데이터 조회 성공 >> " + list.size() + "건 조회됨");
		}
		
		logger.debug("=============== method end >> listAdmin");
		
		return list;
	}
	
	/**
	 * 관리자 계정 리스트조회
	 * @param start - 검색 범위의 시작위치
	 * @param end - 한 페이지에 보여질 글의 목록 수
	 * @return	ArrayList<AdminItem> : 관리자들 계정의 객체배열로 리턴
	 */
	public ArrayList<AdminItem> listAdmin(int start, int end) {
		logger.debug("=============== method start >> listAdmin");
		logger.debug("[PARAMS] start=" + start);
		logger.debug("[PARAMS] end=" + end);
		
		ArrayList<AdminItem> list = null;
		
		// 데이터 조회
		String sql = "SELECT seq, admin_id, admin_pw, admin_level, admin_comment, reg_date, edit_date "
				+ "FROM admin LIMIT %d, %d;";
		
		ResultSet rs = DBHandler.getResult(sql, start, end);
		
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				list = new ArrayList<AdminItem>();
				
				while(rs.next()) {
					
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int admin_seq = rs.getInt(1);
					String admin_id = rs.getString(2);
					String admin_pw = rs.getString(3);
					int admin_level = rs.getInt(4);
					String admin_comment = rs.getString(5);
					String reg_date = rs.getString(6);
					String edit_date = rs.getString(7);
					
					// 2) 추출된 값을 객체로 구성
					AdminItem item = new AdminItem(admin_seq, admin_id, admin_pw, admin_level, admin_comment, reg_date, edit_date);
					
					// 3) ArrayList에 추가
					list.add(item);
				}
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
		
		if(list == null) {
			logger.error("데이터 조회 실패");
		} else {
			logger.debug("데이터 조회 성공 >> " + list.size() + "건 조회됨");
		}
		
		logger.debug("=============== method end >> listAdmin");
		
		return list;
	}
	
	/**
	 * 관리자 로그인
	 * @param	admin_id : 관리자 아이디
	 * @param	admin_pw : 관리자 패스워드
	 * @return	AdminItem : 로그인 처리의 결과유무에 따라 리턴
	 */
	public AdminItem doLogin(String admin_id, String admin_pw) {
		logger.debug("=============== method start >> loginAdmin");
		logger.debug("[PARAMS] admin_id=" + admin_id);
		logger.debug("[PARAMS] admin_pw=" + admin_pw);
		
		AdminItem item = null;
		
		String sql = "SELECT seq, admin_id, admin_pw, admin_level, admin_comment, reg_date, edit_date "
				+ "FROM admin "
				+ "WHERE admin_id = '%s';";
		
		ResultSet rs = DBHandler.getResult(sql, admin_id);
		
		// SQL이 성공이라면?
		if (rs != null) {
			try {
				// 데이터가 있다면?
				if (rs.next()) {
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int admin_seq = rs.getInt(1);
					String adminId = rs.getString(2);
					String adminPw = rs.getString(3);
					int admin_level = rs.getInt(4);
					String admin_comment = rs.getString(5);
					String reg_date = rs.getString(6);
					String edit_date = rs.getString(7);
					
					// 2) 추출된 값을 객체로 구성
					if (admin_pw.equals(adminPw)) {
						item = new AdminItem(admin_seq, adminId, adminPw, admin_level, admin_comment, reg_date, edit_date);
					}
				}
				
				// ResultSet의 자원 반납(메모리 해제)
				rs.close();
				rs = null;
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		logger.debug("=============== method end >> loginAdmin");
		
		return item;
	}
}
